home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / od.arc / OD.DOC next >
Text File  |  1985-05-28  |  7KB  |  344 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. /***
  5.  *    od.c [09/30/84] - binary dump program, like UNIX utility.
  6.  *
  7.  *    Usage:
  8.  *        od [-bcdoxm] [file] [+][offset][.][b]
  9.  *            -b     - output octal bytes
  10.  *            -c     - output character bytes
  11.  *            -d     - output decimal words
  12.  *            -o     - output octal words (default)
  13.  *            -x     - output hex words
  14.  *            -m     - pause for each output screen
  15.  *            file   - input file (stdin default)
  16.  *            offset - start offset
  17.  *
  18.  *        If 'file' is missing input is from standard input and
  19.  *        'offset' must be preceeded by '+'.
  20.  *        File is output starting at `offset` which is an octal
  21.  *        value unless suffixed by `.`, in which case it is decimal.
  22.  *        If `offset` is suffixed by `b` it is multiplied by 512.
  23.  *        (UNIX block size)
  24.  *
  25.  *
  26.  *        It is assumed that ints are two bytes long.
  27.  *
  28.  *        Compiles with CII-C86 ver 2.20d - others may need mods.
  29.  */
  30.  
  31. /*
  32.  *    Copyright, 1984, Selene Associates, Ltd. - All rights reserved.
  33.  *
  34.  *    Permission is granted for the copying and use of this program
  35.  *    if the following conditions are met:
  36.  *
  37.  *        1)    The use is not for direct commercial benefit.
  38.  *            Permission is NOT granted to sell this program
  39.  *            or to incorporate it in any product or for use
  40.  *            as a promotional tool or inducement to buy any
  41.  *            product or service.
  42.  *        2)    The user agrees that this program is distributed
  43.  *            with no warrenties, expressed or implied, as to
  44.  *            its suitablity for use for any purpose.  And the
  45.  *            user assumes full responsibility for any damages
  46.  *            resulting in the use or the inability to use this
  47.  *            program.
  48.  *        3)    That this entire comment block is included in any
  49.  *            copies or modifications of this program.
  50.  *
  51.  *    If you find this program to be of use to you, a donation of
  52.  *    whatever you think it is worth will be cheerfully accepted.
  53.  *
  54.  *    Written by: David L. Messer, Selene Associates, Ltd.
  55.  *                P.O. Box 19130, Mpls, MN,  55119
  56.  */
  57.  
  58. int moreflag ;
  59. int nline ;
  60. #define NLINE    23
  61.  
  62.  
  63. int flags ;
  64.  
  65. #define OFLAG    0x01
  66. #define OIND    0
  67. #define DFLAG    0x02
  68. #define DIND    1
  69. #define XFLAG    0x04
  70. #define XIND    2
  71. #define CFLAG    0x08
  72. #define CIND    3
  73. #define BFLAG    0x10
  74. #define BIND    4
  75.  
  76. int wideflag ;
  77.  
  78.  
  79. union {
  80.     unsigned char bbuf[16] ;
  81.     unsigned wbuf[8] ;
  82.     } buf1, buf2 ;
  83.  
  84.  
  85. main( argc, argv )
  86. int argc ;
  87. char **argv ;
  88. {
  89.     register i,j,k,n ;
  90.     FILE *stream ;
  91.     char *cp ;
  92.     long addr, acc, acc10 ;
  93.  
  94.     stream = stdin ;
  95.     flags = 0 ;
  96.     addr = acc = acc10 = 0L ;
  97.  
  98.     /*
  99.      * Get flags
  100.      */
  101.  
  102.     argv++ ;
  103.     argc-- ;
  104.     if( argc > 0 && **argv == '-' ) {
  105.         cp = *argv ;
  106.         argv++ ;
  107.         argc-- ;
  108.  
  109.         while( *++cp ) {
  110.             switch ( *cp ) {
  111.                 case 'b':
  112.                     flags |= BFLAG ;
  113.                     wideflag++ ;
  114.                     break ;
  115.  
  116.                 case 'c':
  117.                     flags |= CFLAG ;
  118.                     wideflag++ ;
  119.                     break ;
  120.  
  121.                 case 'd':
  122.                     flags |= DFLAG ;
  123.                     break ;
  124.  
  125.                 case 'o':
  126.                     flags |= OFLAG ;
  127.                     break ;
  128.  
  129.                 case 'x':
  130.                     flags |= XFLAG ;
  131.                     break ;
  132.  
  133.                 case 'm':
  134.                     moreflag++ ;
  135.                     break ;
  136.  
  137.                 default:
  138.                     goto usage ;
  139.                 }
  140.             }
  141.         }
  142.  
  143.     /*
  144.      * Get file name and offset.
  145.      */
  146.  
  147.     if( argc > 0 ) {
  148.         if( **argv != '+' ) {
  149.             if( (stream = fopen( *argv, "rb" )) == NULL ) {
  150.                 printf( "od: Can`t open %s\n", *argv ) ;
  151.                 exit( 1 ) ;
  152.                 }
  153.             argv++ ;
  154.             argc-- ;
  155.             }
  156.  
  157.         if( argc ) {
  158.             cp = *argv ;
  159.             if( *cp == '+' ) cp++ ;
  160.  
  161.             while( isdigit( *cp ) ) {
  162.                 acc <<= 3 ;
  163.                 acc10 *= 10 ;
  164.                 acc10 += (long)(*cp - '0') ;
  165.                 acc += (long)(*cp - '0') ;
  166.                 cp++ ;
  167.                 }
  168.             if( *cp == '.' ) {
  169.                 acc = acc10 ;
  170.                 cp++ ;
  171.                 }
  172.             if( *cp == 'b' ) {
  173.                 acc *= 512L ;
  174.                 cp++ ;
  175.                 }
  176.             if( *cp != '\0' ) goto usage ;
  177.             argc-- ;
  178.             }
  179.         }
  180.     if( argc > 0 ) goto usage ;
  181.  
  182.     if( flags == 0 ) flags = OFLAG ;
  183.  
  184.  
  185.     /*
  186.      * Skip bytes for offset.
  187.      */
  188.  
  189.     addr = 0 ;
  190.     while( addr != acc ) {
  191.         if( fgetc( stream ) == EOF ) break ;
  192.         addr++ ;
  193.         }
  194.  
  195.  
  196.     /*
  197.      * Print bytes, 16 at a time.
  198.      */
  199.  
  200.     n = fread( buf1.bbuf, 1, 16, stream ) ;
  201.     while( n > 0 ) {
  202.         if( n&1 ) buf1.bbuf[n] = 0 ;
  203.  
  204.         printf( "%07lo", addr ) ;
  205.  
  206.         for( i=0, k=flags; k; i++ ) {
  207.             if( k&1 ) {
  208.                 for( j=0; j<n; j++ ) {
  209.                     switch( i ) {
  210.                         case OIND:
  211.                             if( wideflag ) putchar( ' ' ) ;
  212.                             printf( " %06lo",
  213.                                     (long)(buf1.wbuf[j/2]) & 0xFFFFL ) ;
  214.                             j++ ;
  215.                             break ;
  216.  
  217.                         case XIND:
  218.                             if( wideflag ) putchar( ' ' ) ;
  219.                             printf( "   %04lx",
  220.                                     (long)(buf1.wbuf[j/2]) & 0xFFFFL ) ;
  221.                             j++ ;
  222.                             break ;
  223.  
  224.                         case DIND:
  225.                             if( wideflag ) putchar( ' ' ) ;
  226.                             printf( "  %05ld",
  227.                                     (long)(buf1.wbuf[j/2]) & 0xFFFFL ) ;
  228.                             j++ ;
  229.                             break ;
  230.  
  231.                         case BIND:
  232.                             printf( " %03o", buf1.bbuf[j] ) ;
  233.                             break ;
  234.  
  235.                         case CIND:
  236.                             if( isprint( buf1.bbuf[j] ) ) {
  237.                                 printf( "   %c", buf1.bbuf[j] ) ;
  238.                                 }
  239.                             else switch( buf1.bbuf[j] ) {
  240.                                 case '\0':
  241.                                     printf( "  \\0" ) ;
  242.                                     break ;
  243.  
  244.                                 case '\b':
  245.                                     printf( "  \\b" ) ;
  246.                                     break ;
  247.  
  248.                                 case '\f':
  249.                                     printf( "  \\f" ) ;
  250.                                     break ;
  251.  
  252.                                 case '\n':
  253.                                     printf( "  \\n" ) ;
  254.                                     break ;
  255.  
  256.                                 case '\r':
  257.                                     printf( "  \\r" ) ;
  258.                                     break ;
  259.  
  260.                                 case '\t':
  261.                                     printf( "  \\t" ) ;
  262.                                     break ;
  263.  
  264.                                 default:
  265.                                     printf( " %03o", buf1.bbuf[j] ) ;
  266.                                 }
  267.                             break ;
  268.                         }
  269.                     }
  270.                 putchar( '\n' ) ;
  271.                 more() ;
  272.                 k >>= 1 ;
  273.                 if( k ) printf( "       " ) ;
  274.                 }
  275.             else k >>= 1 ;
  276.             }
  277.  
  278.         k = 0 ;
  279.         addr += n ;
  280.         if( n < 16 ) break ;
  281.         for(;;) {
  282.             n = fread( buf2.bbuf, 1, 16, stream ) ;
  283.             j = 0 ;
  284.             for( i=0; i<n; i++ ) {
  285.                 if( buf1.bbuf[i] != buf2.bbuf[i] ) j=1 ;
  286.                 }
  287.             if( j==0 && k==0 && n > 0 ) {
  288.                 printf( "*\n" ) ;
  289.                 more() ;
  290.                 k++ ;
  291.                 }
  292.             if( n!=16 || j!=0 ) break ;
  293.             addr += n ;
  294.             }
  295.  
  296.         for( i=0; i<n; i++ ) {
  297.             buf1.bbuf[i] = buf2.bbuf[i] ;
  298.             }
  299.         }
  300.  
  301.     printf( "%07o\n", addr ) ;
  302.     more() ;
  303.     exit( 0 ) ;
  304.  
  305.  
  306.     usage:
  307.         printf( "od [-bcdoxm] [file] [+][offset][.][b]\n" ) ;
  308.         printf( "    -b     - output octal bytes\n" ) ;
  309.         printf( "    -c     - output character bytes\n" ) ;
  310.         printf( "    -d     - output decimal words\n" ) ;
  311.         printf( "    -o     - output octal words (default)\n" ) ;
  312.         printf( "    -x     - output hex words\n" ) ;
  313.         printf( "    -m     - pause for each output screen\n" ) ;
  314.         printf( "    file   - input file (stdin default)\n" ) ;
  315.         printf( "    offset - start offset\n" ) ;
  316.         exit( 1 ) ;
  317.  
  318.     } /* main */
  319.  
  320.  
  321.  
  322.  
  323.  
  324. /**
  325.  *    more - if moreflag is set, pause every screen.  Must be called
  326.  *           for every line-feed.
  327.  */
  328.  
  329. more()
  330. {
  331.     char c ;
  332.  
  333.     if( !moreflag ) return ;
  334.  
  335.     if( ++nline < NLINE ) return ;
  336.     nline = 0 ;
  337.     printf( "--More--" ) ;
  338.     while( (c = bdos(8)&0x7F) != ' ' && c != 'q' ) {
  339.         }
  340.     printf( "\r        \r" ) ;
  341.     if( c == 'q' ) exit( 0 ) ;
  342.  
  343.     } /* more */
  344.